#ifndef BASERSUCTRL_H
#define BASERSUCTRL_H

#include <QObject>
#include <QTimer>
#include "datastructure.h"

class BaseRsuCtrl : public QObject
{
    Q_OBJECT
public:
    explicit BaseRsuCtrl(QObject *parent = 0);
    ~BaseRsuCtrl();

public:
    void setId(int nId)
    {
        m_nId = nId;
    }
    int getId()
    {
        return m_nId;
    }

protected:
    int m_nId;

public:
    /*!
     * \brief 设置天线连接参数，打开天线
     * \param host: 天线IP地址
     * \param port: 天线服务监听端口
     */
    void openRsu(const QString &host, quint16 port)
    {
        m_sRsuHost=host;
        m_nRsuPort=port;
        reopenRsu();
    }

    /*!
     * \brief 打开天线
     */
    virtual void reopenRsu()=0;

    /*!
     * \brief 关闭天线
     */
    virtual void closeRsu()=0;

protected:
    QString m_sRsuHost;
    quint16 m_nRsuPort;

public:
    static void fillCurrentTime(quint8 *Time);

public:
    /*!
     * \brief 初始化RSU
     * \param nBSTInterval
     * \param nTxPower
     * \param nPLLChannelID
     */
    int initRsu(int nBSTInterval, int nTxPower, int nPLLChannelID);

    /*!
     * \brief 初始化RSU
     */
    virtual int initRsu()=0;

    /*!
     * \brief 获取RSU信息
     */
    virtual int getRsuInfo()
    {
        // 不在基类实现
        return -1;
    }

    virtual int detectObu()
    {
        // 不在基类实现
        return -1;
    }

    virtual void releaseObu(quint32 nMacId)
    {
        Q_UNUSED(nMacId);
    }

    virtual void releaseCurrentObu()
    {
    }

    /*!
     * \brief 检查Rsu状态，如果需要检查RSU状态并发出检查指令，返回true，否则返回false。
     *      该返回值被定期检测OBU的定时器使用，以判断是否需要发出OBU搜寻帧。
     */
    virtual bool checkRsuStatus()
    {
        // 不在基类实现
        return false;
    }

    /*!
     * \brief 尝试重新连接设备。
     */
    void tryReconnect();

public:
    /*!
     * \brief 设备状态：正常
     */
    const static int DEV_STATUS_OK      = 0;
    /*!
     * \brief 设备状态：错误
     */
    const static int DEV_STATUS_ERR     = 1;
    /*!
     * \brief 设备状态：正在打开
     */
    const static int DEV_STATUS_OPENING = 2;
    const static int DEV_STATUS_CLOSING = 3;
    const static int DEV_STATUS_CLOSED  = 4;
    /*!
     * \brief 设备状态：初始值，内部使用
     */
    const static int DEV_STATUS_INIT=999;

protected:
    void setStatus(const int newStatus)
    {
        if (newStatus!=m_status)
        {
            m_status = newStatus;
            emit statusChanged(m_nId, newStatus);
        }

        if (DEV_STATUS_OK==newStatus)
        {
            m_nDevOKTime = QDateTime::currentMSecsSinceEpoch();
            m_nNoResponseErrorCount = 0;
        }
    }

protected:
    int m_status;           /*!< 设备状态 */
    qint64 m_nDevOKTime;    /*!< 设备连接正常时间，主要用于心跳检测 */
    int m_nNoResponseErrorCount;

signals:
    void newFrameArrived(quint8 nFrameIndex, quint8 nFrameType, const QByteArray &frame);
    void rsuInited(int nRsuStatus, const QByteArray &baRsuInfo);
    void rsuInfoGot(const QByteArray &baRsuInfo);
    void obuDetected(ObuInfo newObu, IccInfo newIcc);
    void statusChanged(int nIndex, int status);

public:
    void setBeaconChangeInterval(int nInterval)
    {
        m_nBeaconChangeInterval=nInterval;
    }

protected:
    void modifyBeaconId();
    int m_nBeaconChangeInterval;
    quint8 m_BeaconId[8];

public:
    static int getValueWithConfine(int n, int nMin, int nMax)
    {
        if (n<nMin) n=nMin;
        if (n>nMax) n=nMax;
        return n;
    }

    void configBstInterval(int nInterval)
    {
        m_bstInterval=getValueWithConfine(nInterval, 1, 10);
    }

    void configRsuPower(int nPower)
    {
        m_rsuPower=getValueWithConfine(nPower, 0, 33);
    }

    void configRsuChannel(int nChannel)
    {
        m_rsuChannel=(nChannel==0)?0:1;
    }

    void configRsuHeartBeatCheckStyle(int nStyle)
    {
        m_nRsuHeartBeatCheckStyle=nStyle;
    }

    void configHeartBeatCheckInterval(int nInterval)
    {
        m_nHeartBeatCheckInterval=getValueWithConfine(nInterval, 5*1000, 3600*1000);
    }

    virtual void configRsuType(const QString &rsuType)
    {
        Q_UNUSED(rsuType);
    }

protected:
    int m_bstInterval;
    int m_rsuPower;
    int m_rsuChannel;
    int m_nRsuHeartBeatCheckStyle;
    int m_nHeartBeatCheckInterval;

public:
    /*!
     * \brief 模拟RSU收到的信息帧，模拟测试用
     */
    virtual void mockRawFrameData(QByteArray &frame)=0;

signals:

public slots:
};

#endif // BASERSUCTRL_H
